/**
 * Class Ajax()
 * 
 * @name Ajax
 * @super XMLHttpRequest
 * @constructor
 * @author Hermann D. Schimpf <hschimpf@gschimpf.com>
 * @license http://opensource.org/licenses/gpl-2.0.php
 * @date 2010-07-17
 * @version 0.1.1
 */
function Ajax() {};
Ajax.prototype = new XMLHttpRequest;
Ajax.prototype.callback = null;
Ajax.prototype.progress = null;
/**
 * Realiza una peticion GET
 * 
 * @param String Url para la peticion
 * @param Object Parametros a pasar en la peticion
 * @param Boolean True para ejecutar la peticion asincronamente, default False
 * @return
 */
Ajax.prototype.get = function(url, args, async) {
	/* realizamos la peticion GET */
	return this.request('GET', url, args, async);
};
/**
 * Realiza una peticion POST
 * 
 * @param String Url para la peticion
 * @param Object Parametros a pasar en la peticion
 * @param Boolean True para ejecutar la peticion asincronamente, default False
 * @return
 */
Ajax.prototype.post = function(url, args, async) {
	/* realizamos la peticion POST */
	return this.request('POST', url, args, async);
};
/**
 * Realiza una peticion GET o POST
 * 
 * @param String Tipo de peticion a realizar (GET o POST)
 * @param String Url para la peticion
 * @param Object Parametros para enviar en la peticion
 * @param Boolean True para real la peticion asincronamente, default False
 * @return String Resultado de la peticion
 */
Ajax.prototype.request = function(type, url, args, async) {
	/* seteamos el tipo de peticion */
	var asyncOk = async === undefined || async !== true ? false : true;
	/* verificamos si se seteo la funcion para onProgress */
	if (this.progress !== null)
		/* seteamos la funcion onProgress */
		this.onprogress = this.progress;
	/* armamos la peticion */
	this.open(type, url, asyncOk);
	/* especificamos el tipo de contenido */
	this.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	/* realizamos la peticion y enviamos los parametros */
	this.send(this.buildArgs(args));
	/* verificamos si la peticion es asincrona */
	if (asyncOk === false)
		/* retornamos el resultado de la peticion */
		return this.responseText;
	/* creamos un puntero */
	var puntero = this;
	/* seteamos el metodo que procesa el resultado */
	this.onreadystatechange = function() {
		/* ejecutamos el proceso */
		puntero.processResult();
	};
	/* retornamos true */
	return true;
};
/**
 * Arma los parametros para la peticion
 * 
 * @param Object Parametros para la peticion
 * @return String Parametros formateados
 */
Ajax.prototype.buildArgs = function(args) {
	/* creamos una variable de parametros */
	var params = args === undefined || typeof args != 'object' ? null : args;
	/* verificamos si hay parametros */
	if (params === null)
		/* retornamos */
		return params;
	/* creamos una variable para armar la cadena */
	var retorno = '';
	/* recorremos los parametros */
	for ( var i in params)
		/* agregamos el parametro */
		retorno += (retorno === '' ? '' : '&') + i + '=' + params[i];
	/* retornamos los nuevos parametros */
	return retorno;
};
/**
 * Procesa el resultado de una peticion asincrona
 * 
 * @throws AjaxException Error si la peticion falla
 */
Ajax.prototype.processResult = function() {
	/* verificamos el estado de la peticion */
	if (this.readyState == 4 && this.status == 200) {
		/* verificamos si se especifico un callback */
		if (this.existsCallback())
			/* ejecutamos la funcion configurada enviando el resultado */
			this.getCallback()(this.responseText);
		/* verificamos si da error */
	} else if (this.readyState == 4)
		/* mostramos un mensaje */
		throw new AjaxException(this.status + ': ' + this.responseText);
};
/**
 * Almacena la funcion callback para ejecutar en una peticion asincrona
 * 
 * @param Function Funcion para callback
 */
Ajax.prototype.setCallback = function(callback) {
	/* guardamos la funcion para callback */
	this.callback = typeof callback == 'function' ? callback : null;
};
/**
 * Almacena la funcion que se ejecuta durante el progreso de carga
 * 
 * @param Function Funcion para ejecucion durante la carga
 */
Ajax.prototype.setOnprogress = function(func) {
	/* almacenamos la function para onProgress */
	this.progress = typeof func == 'function' ? func : null;
};
/**
 * Retorna si existe una function para callback
 * 
 * @return Boolean True si existe una funcion callback
 */
Ajax.prototype.existsCallback = function() {
	/* retornamos si existe una funcion como callout */
	return typeof this.callback == 'function';
};
/**
 * Retorna la funcion configurada como callback
 * 
 * @return Function Funcion callback
 */
Ajax.prototype.getCallback = function() {
	/* retornamos la funcion configurada */
	return this.callback;
};